﻿ 
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
 
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Logging;
 
using Microsoft.Extensions.Options;
using com.iot.core.infrastructure;
using com.iot.core.boot.configuration;
using NLog.Web;
using NLog.Extensions.Logging;
using com.iot.core.util;
using com.iot.core.data;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using com.iot.core.data.service;
using Microsoft.Extensions.Caching.Distributed;

namespace com.iot.core.boot
{
    public static class ServiceCollectionExtensions
    {
        public static void ConfigureApplicationSettings(this IServiceCollection services,
          WebApplicationBuilder builder)
        {
            //let the operating system decide what TLS protocol version to use
            //see https://docs.microsoft.com/dotnet/framework/network-programming/tls
            ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;

            //create default file provider
            CommonHelper.DefaultFileProvider = new NopFileProvider(builder.Environment);

            //register type finder
            var typeFinder = new WebAppTypeFinder();
            Singleton<ITypeFinder>.Instance = typeFinder;
            services.AddSingleton<ITypeFinder>(typeFinder);

            //add configuration parameters
            var configurations = typeFinder
                .FindClassesOfType<IConfig>()
                .Select(configType => (IConfig)Activator.CreateInstance(configType))
                .ToList();

            foreach (var config in configurations)
                builder.Configuration.GetSection(config.Name).Bind(config,
                    options => options.BindNonPublicProperties = true);


            var appSettings = AppSettingsHelper.SaveAppSettings(configurations, CommonHelper.DefaultFileProvider, false);
            services.AddSingleton(appSettings);
        }


        public static void ConfigureApplicationServices(this IServiceCollection services,
            WebApplicationBuilder builder)
        {

            builder.Logging.ClearProviders();
            builder.Host.UseNLog();
            services.AddLogging(n =>
            {
                n.AddNLog();
            });
         

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();


            var dbConnCfg = Singleton<AppSettings>.Instance.Get<DBConnCfg>();
            services.AddPooledDbContextFactory<IotDbContext>(b =>
            {
                 
                switch (dbConnCfg.DataProvider)
                {
                    case "mysql":
                        b.UseMySql(dbConnCfg.ConnectionString, ServerVersion.AutoDetect(dbConnCfg.ConnectionString));
                        break;
                    default :
                        b.UseSqlite(dbConnCfg.ConnectionString);
                        break;
                }
                var environment = Singleton<IWebHostEnvironment>.Instance;
                if(environment!=null&&environment.IsDevelopment())
                {
                    b.UseLoggerFactory(LoggerFactory.Create(builder =>
                    {
                        //builder.AddNLog();
                        builder.AddConsole();
                    }));
                }                 
            }, dbConnCfg.PoolSize);

            services.AddScoped<IotDbContext>(p => p.GetRequiredService<IDbContextFactory<IotDbContext>>().CreateDbContext());





            services.AddScoped(typeof(IRepository<>), typeof(Repository<>));

            services.AddScoped(typeof(IBaseService<>), typeof(BaseService<>));


            services.AddScoped<MyContext>();

            services.AddScoped<IHtUserDeptService,HtUserDeptService>();
            services.AddScoped<IHtUserRoleService, HtUserRoleService>();
            services.AddScoped<IHtRoleMenuService, HtRoleMenuService>();




            var redisCfg = Singleton<AppSettings>.Instance.Get<RedisCfg>();
            if (redisCfg.ConnectionString != "")
            {
                var csredis = new CSRedis.CSRedisClient(redisCfg.ConnectionString);
                //初始化 RedisHelper
                RedisHelper.Initialization(csredis);
                //注册mvc分布式缓存
                services.AddSingleton<IDistributedCache>(new Microsoft.Extensions.Caching.Redis.CSRedisCache(RedisHelper.Instance));
            }

            //initialize plugins
            var mvcCoreBuilder = services.AddControllers(opt =>
            {
                opt.Filters.Add( typeof(MyFilter) );
            });
             
            

            mvcCoreBuilder.AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new LowercaseContractResolver();
                options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
                options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;
                options.SerializerSettings.DateFormatString =  DateUtil.DateFormatString;
                options.SerializerSettings.Formatting = Formatting.Indented; //空格
                var mylong = new  MyLongConvert();
                options.SerializerSettings.Converters.Add(mylong);

                 
            });

            services.AddHttpClient();



            //create engine and configure service provider
            var engine = EngineContext.Create();

            engine.ConfigureServices(services, builder.Configuration);
        }

         

    }
}
